cmake_minimum_required(VERSION 3.15)
project(CloudLinker VERSION 0.1.0 LANGUAGES CXX)

# 设置基本编译选项
set(CMAKE_CXX_STANDARD 17)  # 提升到C++17以支持更多现代特性
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# 定义DLL构建宏
if(WIN32)
    add_definitions(-DCLINK_BUILDING_DLL)
endif()

# 根据平台设置 VCPKG_ROOT
if(WIN32)
    set(VCPKG_ROOT "D:/vcpkg")
else()
    #set(VCPKG_ROOT "/home/serveropen/vcpkg")
endif()

# vcpkg集成
set(CMAKE_TOOLCHAIN_FILE "${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "")

if(MSVC)
    list(APPEND CMAKE_PREFIX_PATH "${VCPKG_ROOT}/installed/x64-windows")
    set(Poco_DIR "${VCPKG_ROOT}/installed/x64-windows/share/poco")
    
    # 添加库目录，区分debug和release
    if(CMAKE_BUILD_TYPE STREQUAL "Debug")
        link_directories("${VCPKG_ROOT}/installed/x64-windows/debug/lib")
        message(STATUS "Using debug libraries from ${VCPKG_ROOT}/installed/x64-windows/debug/lib")
    else()
        link_directories("${VCPKG_ROOT}/installed/x64-windows/lib")
        message(STATUS "Using release libraries from ${VCPKG_ROOT}/installed/x64-windows/lib")
    endif()
else()
    list(APPEND CMAKE_PREFIX_PATH "${VCPKG_ROOT}/installed/x64-linux")
    set(Poco_DIR "${VCPKG_ROOT}/installed/x64-linux/share/poco")
endif()

# 设置输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

# 查找依赖库
if(WIN32)
    # Windows平台只需要查找Data模块，它已包含MySQL和SQLite支持
    find_package(Poco REQUIRED COMPONENTS Foundation Net NetSSL Util JWT Data)
else()
    # Linux平台需要查找Data和DataSQLite模块
    find_package(Poco REQUIRED COMPONENTS Foundation Net NetSSL Util JWT Data DataSQLite)
endif()
find_package(Poco REQUIRED COMPONENTS JSON)

# 如果找不到Poco::JSON，尝试使用其他方式
if(NOT TARGET Poco::JSON)
    message(STATUS "Trying alternative method to find Poco::JSON")
    find_package(Poco REQUIRED)
    # 检查是否有JSON库
    if(EXISTS "${Poco_INCLUDE_DIRS}/Poco/JSON/JSON.h")
        message(STATUS "Found Poco JSON headers at ${Poco_INCLUDE_DIRS}/Poco/JSON/JSON.h")
    else()
        message(WARNING "Poco JSON headers not found!")
    endif()
endif()
#find_package(ODB REQUIRED)

# 设置编译选项
if(MSVC)
    add_compile_options(/W4)
else()
    add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# 包含目录
include_directories(
    ${PROJECT_SOURCE_DIR}/include
    ${POCO_INCLUDE_DIRS}
)

# 函数：自动发现指定目录下的所有源文件
function(discover_module_sources out_var module_path)
    file(GLOB_RECURSE sources
        "${module_path}/*.cpp"
        "${module_path}/*.cxx"
        "${module_path}/*.cc"
    )
    set(${out_var} ${sources} PARENT_SCOPE)
endfunction()

# 收集所有模块的源文件
set(ALL_SOURCES "")
discover_module_sources(ERROR_SOURCES ${PROJECT_SOURCE_DIR}/src/error)
discover_module_sources(UTILS_SOURCES ${PROJECT_SOURCE_DIR}/src/Utils)
discover_module_sources(AUTH_SOURCES ${PROJECT_SOURCE_DIR}/src/Authentication)
discover_module_sources(ROUTER_SOURCES ${PROJECT_SOURCE_DIR}/src/Router)
discover_module_sources(SERVER_SOURCES ${PROJECT_SOURCE_DIR}/src/Server)
discover_module_sources(DB_SOURCES ${PROJECT_SOURCE_DIR}/src/database)
discover_module_sources(APP_SOURCES ${PROJECT_SOURCE_DIR}/src/App)

# 合并所有源文件
list(APPEND ALL_SOURCES 
    ${ERROR_SOURCES}
    ${UTILS_SOURCES}
    ${AUTH_SOURCES}
    ${ROUTER_SOURCES}
    ${SERVER_SOURCES}
    ${DB_SOURCES}
    ${APP_SOURCES}
)

# 创建单一的共享库
add_library(CloudLinker SHARED ${ALL_SOURCES})

# 设置库的属性
set_target_properties(CloudLinker PROPERTIES
    VERSION ${PROJECT_VERSION}
    SOVERSION ${PROJECT_VERSION_MAJOR}
    DEFINE_SYMBOL "CLINK_BUILDING_DLL"
    OUTPUT_NAME "clink"
)

# 设置Windows DLL导出属性
if(MSVC)
    set_target_properties(CloudLinker PROPERTIES
        WINDOWS_EXPORT_ALL_SYMBOLS TRUE
    )
endif()

# 设置库的包含目录
target_include_directories(CloudLinker PUBLIC
    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

# 链接依赖库
if(WIN32)
    target_link_libraries(CloudLinker
        Poco::Foundation
        Poco::Net
        Poco::NetSSL
        Poco::JSON
        Poco::Util
        Poco::JWT
        Poco::Data
    )
else()
    target_link_libraries(CloudLinker
        Poco::Foundation
        Poco::Net
        Poco::NetSSL
        Poco::JSON
        Poco::Util
        Poco::JWT
        Poco::Data
        Poco::DataSQLite
    )
endif()

# 安装库
install(TARGETS CloudLinker
    EXPORT CloudLinkerTargets
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION bin
    INCLUDES DESTINATION include
)

# 安装头文件
install(DIRECTORY include/CLink
        DESTINATION include
        FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp"
)

# 导出配置
install(EXPORT CloudLinkerTargets
        FILE CloudLinkerTargets.cmake
        NAMESPACE CloudLinker::
        DESTINATION lib/cmake/CloudLinker
)

# 创建配置文件
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
    "${CMAKE_CURRENT_BINARY_DIR}/CloudLinkerConfigVersion.cmake"
    VERSION ${PROJECT_VERSION}
    COMPATIBILITY SameMajorVersion
)

configure_package_config_file(
    "${CMAKE_CURRENT_SOURCE_DIR}/cmake/CloudLinkerConfig.cmake.in"
    "${CMAKE_CURRENT_BINARY_DIR}/CloudLinkerConfig.cmake"
    INSTALL_DESTINATION lib/cmake/CloudLinker
)

# 安装配置文件
install(FILES
    "${CMAKE_CURRENT_BINARY_DIR}/CloudLinkerConfig.cmake"
    "${CMAKE_CURRENT_BINARY_DIR}/CloudLinkerConfigVersion.cmake"
    DESTINATION lib/cmake/CloudLinker
)

# 调试程序配置
option(BUILD_DEBUG "Build debug program" ON)
if(BUILD_DEBUG)
    #add_executable(debug_app main.cpp ${ALL_SOURCES})
    add_executable(debug_app main.cpp)
    target_link_libraries(debug_app
        CloudLinker
    )
endif()

# 示例程序配置
option(BUILD_EXAMPLES "Build example programs" ON)
if(BUILD_EXAMPLES)

endif()